home *** CD-ROM | disk | FTP | other *** search
- Unit Modempro ;
- (* ================================================================= *)
- (* MODEM - Routines and Global variables for IBMPC compatiables. *)
- (* ================================================================= *)
- Interface
- Uses Dos,Crt, (* Standard Turbo Pascal Units *)
- KGlobals ; (* Kermit Globals - Execution control Flags *)
- Type
- ParityType = (OddP,EvenP,MarkP,NoneP) ;
- Const
- DefaultBaud = 9600 ;
- Var
- PrimaryPort : Boolean ;
- Baudrate : Integer ;
- Parity : ParityType ;
- Procedure Initmodem ;
- Procedure ResetModem;
- Procedure SetModem ;
- Procedure AnswerModem ;
- Procedure DialModem ;
- Function RecvChar (var mchar : byte) : boolean ;
- Function CharsInBuffer : integer ;
- Procedure EmptyBuffer ;
- Procedure SendChar (char : byte ) ;
- Procedure SendBreak ;
-
- (* ================================================================= *)
- Implementation
- CONST
- (* Modem Registers *)
- LowOrderDiv = 0 ;
- HiOrderDiv = 1 ; InterruptEnable = 1 ;
- InterruptIdReg = 2 ;
- LineControlReg = 3 ;
- ModemControlReg = 4 ;
- LineStatusReg = 5 ;
- ModemStatusReg = 6 ;
- ClockRate = 18430 ; (* CentiHertz. - use 17895 for PCjr *)
- (* 8259 Interrupt Controller addresses *)
- (* IC8259Reg1 = $20 ; IC8259Reg2 = $21 ; *)
- MaxBuffsize = 32760 ;
-
- VAR
- Modem : Integer ;
- IntNumber,
- EnableMask,ResetMask,SaveMask : byte ;
- DSRcheck : boolean ;
- OldVector : pointer ;
- Iout,Iin : integer ;
- Buffer : Packed array [1..MaxBuffsize] of byte ;
-
- (* ------------------------------------------------------------------ *)
- (* IntHandler - Interrupt handler *)
- (* This procedure handles the modem interrupts , *)
- (* which occur for incomming data only. *)
- (* ------------------------------------------------------------------ *)
- Procedure IntHandler ;
- Interrupt ;
- Begin (* IntHandler *)
- Inline($FB) ; (* STI set interrupt enable *)
- While (Port[Modem+LineStatusReg] and $01) = $01 do
- begin (* put char in buffer *)
- buffer[Iin] := Port[Modem];
- Iin := Iin + 1 ;
- if Iin = MaxBuffsize then Iin := 1 ;
- end ; (* put char in buffer *)
- Port[$20] := ResetMask ;
- End ; (* IntHandler *)
-
- (* ------------------------------------------------------------------ *)
- (* InitModem - Initialize the modem and setup interrupt procedure. *)
- (* ------------------------------------------------------------------ *)
- Procedure Initmodem ;
- Var rate : integer ;
- Begin (* Init modem *)
- If PrimaryPort then
- Begin (* Primary port *)
- Modem := $3F8 ;
- EnableMask := $EF ;
- ResetMask := $64 ; (* end of interrupt for IRQ4 *)
- IntNumber := 12 ;
- End (* Primary Port *)
- else
- Begin (* Secondary Port *)
- Modem := $2F8 ;
- EnableMask := $F7 ;
- ResetMask := $63 ; (* end of interrupt for IRQ3 *)
- IntNumber := 11 ;
- End ; (* Secondary Port *)
- Iin := 1 ; Iout := 1 ;
-
- (* Initialize the Serial port Interrupt Procedure *)
- GetIntVec(IntNumber,Oldvector) ; (* save the Old interrupt handler *)
- SetIntVec (IntNumber,@IntHandler) ; (* Use our own interrupt handler *)
- SaveMask := Port[$21] ; (* save setting *)
- Port[$21] := Port[$21] and EnableMask ; (* Enable serial port interrupt *)
- Port[$20] := ResetMask ;
-
- (* Initialize baud rates and bits and parity *)
- Rate := round( (Clockrate/16) / (Baudrate/100)) ;
- Port[Modem+LineControlReg] := $80 ; (* Enable baud rate setting *)
- Port[Modem+LowOrderDiv] := (rate and $00FF) ;
- Port[Modem+HiOrderDiv] := rate div $100 ;
- Port[Modem+LineControlReg] := (ord(Parity) shl 4) OR $0A ;
- (* parity, 7 bits,1 stop *)
- Port[Modem+ModemControlReg] := $0B ; (* set OUT2, DTR ,RTS *)
- Port[Modem+InterruptEnable] := $01 ; (* Data Avail. Interrupt set *)
- End ; (* Init modem *)
-
- (* ------------------------------------------------------------------ *)
- (* ResetModem - Reset the Interrupt back to the original. *)
- (* Global variables - Saveoffset,SaveSeq *)
- (* ------------------------------------------------------------------ *)
- Procedure ResetModem;
- Begin (* Reset Modem Interrupt *)
- SetIntVec(IntNumber,Oldvector) ; (* restore the Old interrupt handler *)
- Port[$21] := SaveMask ;
- Port[Modem+InterruptEnable] := $00 ; (* Data Avail. Interrupt reset *)
- End; (* Reset Modem Interrupt *)
-
- (* ------------------------------------------------------------------ *)
- (* SetModem - Set the baud rate and parity for modem. *)
- (* Global variables - Modem,Clockrate,Baudrate,Parity *)
- (* ------------------------------------------------------------------ *)
- Procedure SetModem ;
- Var rate : integer ;
- Begin (* SetModem *)
- If PrimaryPort then
- Begin (* Primary port *)
- Modem := $3F8 ;
- EnableMask := $EF ;
- ResetMask := $64 ; (* end of interrupt for IRQ4 *)
- End (* Primary Port *)
- else
- Begin (* Secondary Port *)
- Modem := $2F8 ;
- EnableMask := $F7 ;
- ResetMask := $63 ; (* end of interrupt for IRQ3 *)
- End ; (* Secondary Port *)
- Rate := round( (Clockrate/16) / (Baudrate/100)) ;
- Port[Modem+LineControlReg] := $80 ; (* Enable baud rate setting *)
- Port[Modem+LowOrderDiv] := (rate and $00FF) ;
- Port[Modem+HiOrderDiv] := rate div $100 ;
- Port[Modem+LineControlReg] := (ord(Parity) shl 4) OR $0A ;
- (* parity, 7 bits,1 stop *)
- End ; (* SetModem *)
-
- (* ------------------------------------------------------------------ *)
- (* DialModem - Check and waits for modem to be connected. *)
- (* It waits for DSR signals be detected. *)
- (* Side Effect - global variable 'connected' is set true. *)
- (* ------------------------------------------------------------------ *)
- Procedure DialModem ;
- var i : integer ;
- Begin (* Dial Modem *)
- While ((Port[Modem+ModemStatusReg] and $20) <> $20) and DSRcheck Do
- Begin (* Connect modem please *)
- (* writeln('modem status =',Port[Modem+ModemStatusReg]); *)
- writeln(' Please connect your modem ');
- delay (1000);
- If KeyPressed then (* Bypass DSRcheck by hitting the space bar *)
- DSRcheck := readkey <> ' ' ;
- End ; (* Connect modem please *)
- Port[Modem+ModemControlReg] := $0B ; (* set OUT2, DTR ,RTS *)
- connected := true ;
- If audioflag then
- for i:=1 to 50 do begin sound(100*i); delay(5); end ; nosound;
- Writeln(' Connection completed ');
- End ; (* Dial Modem *)
-
- (* ------------------------------------------------------------------ *)
- (* AnswerModem - Check and waits for modem to be connected. *)
- (* If DCD is off set RTS off. Wait for DCD to get set *)
- (* then set RTS. ( similar to DIALMODEM ) *)
- (* Side Effect - global variable 'connected' is set true. *)
- (* ------------------------------------------------------------------ *)
- Procedure AnswerModem ;
- var count : integer ;
- Begin (* Answer Modem *)
- count := 0 ;
- If (Port[Modem+ModemStatusReg] and $80) <> $80 then
- Port[Modem+ModemControlReg] := $09 ; (* set OUT2,DTR reset RTS *)
- clrscr ; GotoXY(10,10);
- write(' Waiting for someone to connect ');
- While ((Port[Modem+ModemStatusReg] and $80) <> $80) Do
- Begin (* Connect modem please *)
- Gotoxy( 44,10) ; write(count);
- delay (1000); count := count + 1 ;
- End ; (* Connect modem please *)
- Port[Modem+ModemControlReg] := $0B ; (* set OUT2, DTR ,RTS *)
- Writeln(' Answer completed ');
- End ; (* Answer Modem *)
-
- (* ------------------------------------------------------------------ *)
- (* RecvChar - Receive a Character from the modem port. *)
- (* TRUE - if there is a character from the modem and *)
- (* the character is returned in the parmeter. *)
- (* FALSE - if no character found . *)
- (* *)
- (* ------------------------------------------------------------------ *)
- Function RecvChar (var mchar : byte) : boolean ;
- Begin (* RecvChar *)
- if Iin <> Iout then
- begin (* get char from buffer *)
- If Parity = NoneP then mchar := buffer[Iout]
- else mchar := buffer[Iout] and $7F ;
- Iout := Iout + 1 ;
- If Iout = MaxBuffsize then Iout := 1 ;
- RecvChar := true ;
- if logging then
- Begin {$I-}
- write(Logfile,chr(mchar));
- If IOresult <> 0 then
- Begin (* IO error *)
- Writeln(' Disk is Full - logging teminated');
- logging := false ;
- Close(Logfile);
- End ; (* IO error *)
- End ; {$I+}
- end (* get char from buffer *)
- else
- RecvChar := false ;
- End ; (* RecvChar *)
-
- (* ------------------------------------------------------------------ *)
- (* SendChar - Send a character thru the modem port. *)
- (* It waits for the previous character to be sent before *)
- (* sending the current character. *)
- (* ------------------------------------------------------------------ *)
- Procedure SendChar(char : byte ) ;
- Begin (* Send Char *)
- While (Port[Modem+LineStatusReg] and $20) <> $20 do delay(1);
- Port[modem] := char ;
- End ; (* Send Char *)
-
- (* ------------------------------------------------------------------ *)
- (* CharsInBuffer - Returns the number of unprocessed characters in *)
- (* the Buffer. *)
- (* ------------------------------------------------------------------ *)
- Function CharsInBuffer : integer ;
- Begin (* Chars In Buffer *)
- If Iin >= Iout then CharsInBuffer := Iin - Iout
- else CharsInBuffer := MaxBuffSize - Iout + Iin ;
- End ; (* Chars In Buffer *)
-
- (* ------------------------------------------------------------------ *)
- (* EmptyBuffer - Mark the buffer as being empty. *)
- (* ------------------------------------------------------------------ *)
- Procedure EmptyBuffer ;
- Begin (* Empty Buffer *)
- Iout := Iin ;
- End ; (* Empty Buffer *)
-
- (* ------------------------------------------------------------------ *)
- (* SendBreak- Send a break via the modem port . *)
- (* ------------------------------------------------------------------ *)
- Procedure SendBreak ;
- Var Tbyte,dummy : byte ;
- Begin (* Send Break *)
- Tbyte := Port[Modem+LineControlReg] ; (* save setting *)
- Port[Modem+InterruptEnable] := $00 ; (* Data Avail. Interrupt reset *)
- Port[Modem+LineControlReg] := $40 ; (* break for 200 millsec *)
- GoToXy(1,24); Write(' *** BREAK *** ',chr(07));
- Delay(200) ;
- Port[Modem+LineControlReg] := Tbyte ; (* restore setting *)
- Delay(100) ;
- dummy := Port[Modem] ; (* clear out incoming char *)
- Port[Modem+InterruptEnable] := $01 ; (* Data Avail. Interrupt set *)
- End ; (* Send Break *)
-
- (* ================================================================= *)
- (* End of MODEM routines for IBMPC compatiables. *)
- (* ================================================================= *)
- Begin
- Baudrate := DefaultBaud ;
- PrimaryPort := True ;
- Parity := EvenP ;
- InitModem ;
- DSRcheck := True ;
- End. (* Modempro *)